﻿using Serilog.Events;
using Serilog;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Serilog.Sinks.SystemConsole.Themes;

namespace HECore.SerilogWebApi.Extensions
{
    /// <summary>
    /// ServiceCollection 扩展
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 添加配置Serilog
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static IServiceCollection AddConfigSerilog(this IServiceCollection services, IConfiguration configuration)
        {
            var seqApiKey = configuration["seq:apiKey"].ToString();
            var seqServerUrl = configuration["seq:serverUrl"].ToString();

            // 创建Serilog记录日志
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Verbose()
                .MinimumLevel.Override("System", LogEventLevel.Debug)
                .MinimumLevel.Override("Microsoft", LogEventLevel.Debug)
                .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Error)
                .MinimumLevel.Override("Microsoft.AspNetCore.Cors.Infrastructure.CorsService", LogEventLevel.Error)
                .MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Error)
                .MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Error)
                // 全部日志写入到Console
                .WriteTo.Async(c => c.Console(
                   theme: AnsiConsoleTheme.Literate,
                    outputTemplate: "[T] {Timestamp:yyyy-MM-dd HH:mm:ss,fff} {MachineName}{NewLine}[L] [{Level}]{NewLine}[C] [{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}"))
                // Information日志写入到文件
                .WriteTo.Async(c => c.File(
                    path: "Logs/Information/.txt",
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 1L * 1024 * 1024 * 1024,
                    retainedFileCountLimit: 31,
                    outputTemplate: "[T] {Timestamp:yyyy-MM-dd HH:mm:ss,fff} {MachineName}{NewLine}[L] [{Level}]{NewLine}[C] [{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}",
                    restrictedToMinimumLevel: LogEventLevel.Information))
                // Debug日志写入到文件
                .WriteTo.Async(c => c.File(
                    path: "Logs/Debug/.txt",
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 1L * 1024 * 1024 * 1024,
                    retainedFileCountLimit: 31,
                    outputTemplate: "[T] {Timestamp:yyyy-MM-dd HH:mm:ss,fff} {MachineName}{NewLine}[L] [{Level}]{NewLine}[C] [{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}",
                    restrictedToMinimumLevel: LogEventLevel.Debug))
                // Warning日志写入到文件
                .WriteTo.Async(c => c.File(
                    path: "Logs/Warning/.txt",
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 1L * 1024 * 1024 * 1024,
                    retainedFileCountLimit: 31,
                    outputTemplate: "[T] {Timestamp:yyyy-MM-dd HH:mm:ss,fff} {MachineName}{NewLine}[L] [{Level}]{NewLine}[C] [{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}",
                    restrictedToMinimumLevel: LogEventLevel.Warning))
                // Error日志写入到文件
                .WriteTo.Async(c => c.File(
                    path: "Logs/Error/.txt",
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 1L * 1024 * 1024 * 1024,
                    retainedFileCountLimit: 31,
                    outputTemplate: "[T] {Timestamp:yyyy-MM-dd HH:mm:ss,fff} {MachineName}{NewLine}[L] [{Level}]{NewLine}[C] [{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}",
                    restrictedToMinimumLevel: LogEventLevel.Error))
                // 全部日志写入到Seq
                .WriteTo.Async(c => c.Seq(
                    apiKey: seqApiKey,
                    serverUrl: seqServerUrl))
                .Enrich.FromLogContext()
                .Enrich.WithMachineName()
                // 过滤请求：/health心跳
                .Filter.ByExcluding("RequestPath like '/health%'")
                .CreateBootstrapLogger();

            services.AddSerilog();

            return services;
        }
    }
}
